package com.yk.system.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yk.api.system.dto.GroupDTO;
import com.yk.api.system.dto.VideoDTO;
import com.yk.common.core.domain.BasePageQuery;
import com.yk.common.core.domain.LoginUser;
import com.yk.common.core.domain.PageResult;
import com.yk.common.core.domain.Result;
import com.yk.common.core.utils.LoginHelper;
import com.yk.common.excel.utils.ExcelUtil;
import com.yk.common.log.annotation.Log;
import com.yk.common.log.constant.LogConstants;
import com.yk.common.log.enums.BusinessType;
import com.yk.system.convert.GroupConvert;
import com.yk.system.convert.VideoConvert;
import com.yk.system.entity.Group;
import com.yk.system.entity.Video;
import com.yk.system.service.GroupService;
import com.yk.system.service.VideoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;


/**
 * 摄像头管理 yk-system
 *
 * @author lmx
 * @since 2023-11-07
 */
@Api(tags = "摄像头")
@RestController
@RequestMapping("/video")
@RequiredArgsConstructor
public class VideoController {

    private final VideoService videoService;
    private final VideoConvert videoConvert;
    private final GroupService groupService;
    private final GroupConvert groupConvert;

    @GetMapping("/getByGroup")
    @ApiOperation("摄像头-根据场景查询")
    public Result<List<GroupDTO>> getByGroup() {
        LambdaQueryWrapper<Group> lambda = new LambdaQueryWrapper<>();
        lambda.eq(Group::getCreatedBy, LoginHelper.getLoginUserId());
        List<Group> list = Optional.ofNullable(groupService.list(lambda)).orElse(CollUtil.newArrayList());
        List<GroupDTO> dtoList = CollUtil.newArrayList();
        list.forEach(it -> {
            GroupDTO groupDTO = groupConvert.entity2Dto(it);
            List<VideoDTO> videoDTOS = videoService.listByGroupId(it.getId());
            // token 封装
            videoService.getToken(videoDTOS);
            groupDTO.setVideoDTOList(videoDTOS);
            dtoList.add(groupDTO);
        });
        return Result.data(dtoList);
    }

    @GetMapping("/getByGroupId/{id}")
    @ApiOperation("摄像头-根据场景Id查询")
    public Result<List<VideoDTO>> getByGroupId(@PathVariable Long id) {
        return Result.data(videoService.listByGroupId(id));
    }

    @PostMapping("/getAppByGroupId")
    @ApiOperation("小程序根据场景Id查询摄像头")
    public Result<List<VideoDTO>> getAppByGroupId(@RequestBody VideoDTO param) {
        if (0L == param.getGroupId()){
            return Result.data(CollUtil.newArrayList());
        }
        List<VideoDTO> videoDTOS = videoService.listByParam(param);
        videoService.getToken(videoDTOS);
        return Result.data(videoDTOS);
    }

    @GetMapping("/getById/{id}")
    @ApiOperation("摄像头-查询单个")
    public Result<VideoDTO> getById(@PathVariable(value = "id") Long id) {
        Video video = videoService.getById(id);
        if (Objects.isNull(video)) {
            return Result.fail("摄像头信息不存在");
        }
        VideoDTO dto = videoConvert.entity2Dto(video);
        Group group = groupService.getById(dto.getGroupId());
        if (Objects.nonNull(group)) {
            dto.setGroupName(group.getName());
        }
        videoService.getToken(dto);
        return Result.data(dto);
    }

    @Log(title = "摄像头", businessType = BusinessType.INSERT)
    @PostMapping("/save")
    @ApiOperation("摄像头-新增")
    public Result<Boolean> save(@RequestBody @Validated VideoDTO dto) {
        videoService.save(videoConvert.dto2Entity(dto));
        return Result.data2Log(Boolean.TRUE, LogConstants.ADD + dto.getName());
    }

    @Log(title = "摄像头", businessType = BusinessType.UPDATE)
    @PostMapping("/update")
    @ApiOperation("摄像头-修改")
    public Result<Boolean> updateById(@RequestBody @Validated VideoDTO dto) {
        videoService.updateById(videoConvert.dto2Entity(dto));
        return Result.data2Log(Boolean.TRUE, LogConstants.UPDATE + dto.getName());
    }

    @Log(title = "摄像头", businessType = BusinessType.DELETE)
    @GetMapping("/deleteById/{id}")
    @ApiOperation("摄像头-删除")
    public Result<Boolean> deleteById(@PathVariable(value = "id") Long id) {
        Video video = videoService.getById(id);
        if (Objects.isNull(video)) {
            return Result.fail("摄像头不存在");
        }
        videoService.removeById(id);
        return Result.data2Log(Boolean.TRUE, LogConstants.DELETE + video.getName());
    }

    @PostMapping("/list")
    @ApiOperation("摄像头-查询列表")
    public Result<List<Video>> list(@RequestBody VideoDTO param) {
        final LambdaQueryWrapper<Video> lambda = new QueryWrapper<Video>().lambda();
        buildCondition(lambda, param);
        return Result.data(videoService.list(lambda));
    }

    @PostMapping("/page")
    @ApiOperation("摄像头-分页查询")
    public PageResult<VideoDTO> page(@RequestBody BasePageQuery<VideoDTO> pageParam) {
        LambdaQueryWrapper<Video> lambda = new QueryWrapper<Video>().lambda();
        buildCondition(lambda, pageParam.getParam());
        IPage<VideoDTO> page = videoService
                .page(new Page<>(pageParam.getPageNum(), pageParam.getPageSize()), lambda)
                .convert(videoConvert::entity2Dto);
        if (CollUtil.isNotEmpty(page.getRecords())) {
            page.getRecords().forEach(it -> {
                // 冗余字段
                Group group = groupService.getById(it.getGroupId());
                if (Objects.nonNull(group)) {
                    it.setGroupName(group.getName());
                }
            });
        }
        return PageResult.success(page.getRecords(), page.getTotal());
    }

    /**
     * 构造查询条件
     */
    private void buildCondition(LambdaQueryWrapper<Video> lambda, VideoDTO param) {
        lambda.eq(Video::getCreatedBy, LoginHelper.getLoginUserId());
        lambda.eq(Objects.nonNull(param.getGroupId()), Video::getGroupId, param.getGroupId());
        lambda.like(StrUtil.isNotEmpty(param.getName()), Video::getName, param.getName());
        lambda.orderByDesc(Video::getCreatedAt);
    }

    @ApiOperation("导出")
    @GetMapping("/export")
    public void export(HttpServletResponse response, VideoDTO param) {
        if (Objects.isNull(param) || StrUtil.isEmpty(param.getToken())) {
            return;
        }
        LoginUser loginUser = LoginHelper.getLoginUser(param.getToken());
        if (Objects.isNull(loginUser)) {
            return;
        }
        LambdaQueryWrapper<Video> lambda = new LambdaQueryWrapper<>();
        lambda.eq(Video::getCreatedBy, loginUser.getUserId());
        lambda.eq(Objects.nonNull(param.getGroupId()), Video::getGroupId, param.getGroupId());
        lambda.like(StrUtil.isNotEmpty(param.getName()), Video::getName, param.getName());
        AtomicInteger index = new AtomicInteger(1);
        List<VideoDTO> list = Optional.ofNullable(videoService.list(lambda))
                .orElse(CollUtil.newArrayList())
                .stream()
                .map(it -> {
                    VideoDTO dto = videoConvert.entity2Dto(it);
                    Group group = groupService.getById(it.getGroupId());
                    if (Objects.nonNull(group)) {
                        dto.setGroupName(group.getName());
                    }
                    dto.setIndex(index.getAndIncrement());
                    return dto;
                })
                .collect(Collectors.toList());
        ExcelUtil.exportExcel(list, "数据", "摄像头", VideoDTO.class, response);
    }

}